home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / board / GNUChess4_0_58.lha / gnuchess-4.0 / src / new / search.c < prev    next >
C/C++ Source or Header  |  1992-08-26  |  33KB  |  1,336 lines

  1. /*
  2.  * search.c - C source for GNU CHESS
  3.  *
  4.  * Copyright (c) 1988,1989,1990 John Stanback
  5.  * Copyright (c) 1992 Free Software Foundation
  6.  *
  7.  * This file is part of GNU CHESS.
  8.  *
  9.  * GNU Chess is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2, or (at your option)
  12.  * any later version.
  13.  *
  14.  * GNU Chess is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with GNU Chess; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23. #include "gnuchess.h"
  24. #ifdef QUIETBACKGROUND
  25. short background = 0;
  26. #endif /* QUIETBACKGROUND */
  27. static short int DepthBeyond;
  28. unsigned short int PrVar[MAXDEPTH];
  29. extern char mvstr[4][6];
  30. #ifdef DEBUG
  31. unsigned short DBLINE[MAXDEPTH];
  32. struct leaf *dbptr;
  33. #endif
  34. struct leaf rootnode;
  35. short int restype;
  36. #include "ataks.h"
  37.  
  38. /* ............    MOVE GENERATION & SEARCH ROUTINES    .............. */
  39. inline
  40. void
  41. repetition (short int *cnt)
  42.  
  43. /*
  44.  * Check for draw by threefold repetition.
  45.  */
  46.  
  47. {
  48.   register short i, c;
  49.   register unsigned short m;
  50.   short b[64];
  51.  
  52.   *cnt = c = 0;
  53.   /* try to avoid work */
  54.   if (GameCnt > Game50 + 2)
  55.     {
  56. #ifdef NOMEMSET
  57.       for (i = 0; i < 64; b[i++] = 0) ;
  58. #else
  59.       memset ((char *) b, 0, sizeof (b));
  60. #endif /* NOMEMSET */
  61.       for (i = GameCnt; i >= Game50; i--)
  62.     {
  63.       m = GameList[i].gmove;
  64.       /* does piece exist on diff board? */
  65.       if (b[m & 0xff])
  66.         {
  67.           /* does diffs cancel out, piece back? */
  68.           if ((b[m >> 8] += b[m & 0xff]) == 0)
  69.         --c;
  70.           b[m & 0xff] = 0;
  71.         }
  72.       else
  73.         {
  74.           /* create diff */
  75.           ++c;
  76.           /* does diff cancel out another diff? */
  77.           if (!(b[m >> 8] -= (b[m & 0xff] = board[m & 0xff] +
  78.                   (color[m & 0xff] << 8))))
  79.         --c;;
  80.         }
  81.       /* if diff count is 0 we have a repetition */
  82.       if (c == 0)
  83.         if ((i ^ GameCnt) & 1)
  84.           (*cnt)++;
  85.     }
  86.     }
  87. }
  88.  
  89. int plyscore, globalscore, globalpnt;
  90. void
  91. pick (short int p1, short int p2)
  92.  
  93. /*
  94.  * Find the best move in the tree between indexes p1 and p2. Swap the best
  95.  * move into the p1 element.
  96.  *
  97. */
  98. {
  99.   register struct leaf *p, *q, *r, *k;
  100.   register s0;
  101.   struct leaf temp;
  102.  
  103.   k = p = &Tree[p1];
  104.   q = &Tree[p2];
  105.   s0 = p->score;
  106.   for (r = p + 1; r <= q; r++)
  107.     if ((r->score) > s0)
  108.       {
  109.     s0 = (r->score);
  110.     p = r;
  111.       }
  112.   if (p != k)
  113.     {
  114.       temp = *p;
  115.       *p = *k;
  116.       *k = temp;
  117.     }
  118. }
  119. #ifdef DEBUG40
  120.   int d7flag;
  121. #endif
  122.  
  123. static int TCcount, TCleft;
  124. void
  125. SelectMove (short int side, short int iop)
  126.  
  127.  
  128. /*
  129.  * Select a move by calling function search() at progressively deeper ply
  130.  * until time is up or a mate or draw is reached. An alpha-beta window of
  131.  * -Awindow to +Bwindow points is set around the score returned from the
  132.  * previous iteration. If Sdepth != 0 then the program has correctly
  133.  * predicted the opponents move and the search will start at a depth of
  134.  * Sdepth+1 rather than a depth of 1.
  135.  */
  136.  
  137. {
  138.   static short int i, tempb, tempc, tempsf, tempst, xside, rpt;
  139.   static short int alpha, beta, score;
  140.   static struct GameRec *g;
  141.   int bookflag = false;
  142.   int Jscore;
  143.   unsigned short tmp[MAXDEPTH];
  144.   flag.timeout = false;
  145.   flag.musttimeout = false;
  146.   xside = side ^ 1;
  147. #ifdef DEBUG40
  148.     d7flag = 0;
  149. #endif
  150.   /* if background mode set to infinite */
  151.   if (iop == 2)
  152.     {
  153.       ResponseTime = 9999999;
  154. #ifdef QUIETBACKGROUND
  155.       background = true;
  156. #endif /* QUIETBACKGROUND */
  157.     }
  158.   else
  159.     {
  160.       player = side;
  161.       if (TCflag)
  162.     {
  163.       TCcount = 0;
  164. #ifdef QUIETBACKGROUND
  165.       background = false;
  166. #endif /* QUIETBACKGROUND */
  167.       if (TimeControl.moves[side] < 1)
  168.         TimeControl.moves[side] = 1;
  169.       /* special case time per move specified */
  170.       if (flag.onemove)
  171.         {
  172.           ResponseTime = TimeControl.clock[side] - 100;
  173.           TCleft = 0;
  174.         }
  175.       else
  176.         {
  177.           /* calculate avg time per move remaining */
  178.           ResponseTime = (TimeControl.clock[side] ) / (((TimeControl.moves[side]) *3));
  179.               TCleft = ResponseTime>>1;
  180.            if (TimeControl.moves[side] < 5) TCcount = MAXTCCOUNT - 1;
  181.         }
  182.       if (ResponseTime < 100)
  183.         {
  184.           ResponseTime = 100;
  185.           TCcount = MAXTCCOUNT;
  186.         }
  187.       else if (ResponseTime < 200)
  188.         {
  189.           TCcount = MAXTCCOUNT - 1;
  190.         }
  191.     }
  192.       else
  193.         ResponseTime = MaxResponseTime;
  194.       if(TCleft){TCcount = ((TimeControl.clock[side] - ResponseTime)/2)/TCleft;
  195.       if(TCcount > MAXTCCOUNT)TCcount = 0; else TCcount = MAXTCCOUNT - TCcount;}
  196.     else TCcount = MAXTCCOUNT;
  197.     }
  198.  
  199.   ExtraTime = 0;
  200.   ExaminePosition ();
  201.   score = ScorePosition (side);
  202. #ifdef QUIETBACKGROUND
  203.   if (!background)
  204. #endif /* QUIETBACKGROUND */
  205.     ShowSidetoMove ();
  206. #ifdef notdef
  207.   if (TCflag && TCcount < MAXTCCOUNT)
  208.     if (score < SCORETIME)
  209.       {
  210.     ExtraTime += TCleft;
  211.     TCcount++;
  212.       }
  213. #endif
  214.  
  215. #ifdef QUIETBACKGROUND
  216.   if (!background)
  217. #endif /* QUIETBACKGROUND */
  218.     SearchStartStuff (side);
  219. #ifdef HISTORY
  220. #ifdef NOMEMSET
  221.   for (i = 0; i < 32768; i++)
  222.     history[i] = 0;
  223. #else
  224.   memset ((char *) history, 0, sizeof (history));
  225. #endif /* NOMEMSET */
  226. #endif
  227.   FROMsquare = TOsquare = -1;
  228.   PV = 0;
  229.   if (iop == 1)
  230.     hint = 0;
  231.   for (i = 0; i < MAXDEPTH; i++)
  232.     PrVar[i] = killr0[i] = killr1[i] = killr2[i] = killr3[i] = 0;
  233.   /* set initial window for search */
  234.   alpha = score - ((computer == black) ? BAwindow : WAwindow);
  235.   beta = score + ((computer == black) ? BBwindow : WBwindow);
  236.   rpt = 0;
  237.   TrPnt[1] = 0;
  238.   root = &Tree[0];
  239.   MoveList (side, 1);
  240.   for (i = TrPnt[1]; i < TrPnt[2]; i++) pick (i, TrPnt[2] - 1);
  241.   /* can I get a book move? */
  242.   if (flag.regularstart && Book){    
  243.     flag.timeout = bookflag = OpeningBook (&hint, side);
  244.     if (TCflag) ResponseTime += ResponseTime;
  245.   }
  246.   rootnode = Tree[0];
  247.   /* zero stats for hash table */
  248.   reminus = replus = 0;
  249.   NodeCnt = ETnodes = EvalNodes = HashCnt = FHashAdd = HashAdd = FHashCnt = THashCol = HashCol = 0;
  250.   globalscore = plyscore = score;
  251. #ifdef DEBUG4
  252.   if (debuglevel & 8)
  253.     {
  254.       int j;
  255.       for (j = 1; j < 2; j++)
  256.     {
  257.       int idb;
  258.       for (idb = TrPnt[j]; idb < TrPnt[j + 1]; idb++)
  259.         {
  260.           algbr (Tree[idb].f, Tree[idb].t, Tree[idb].flags);
  261.           printf ("level 8 %d-->%d %s %d %d\n", j, idb, mvstr[0], Tree[idb].score, Tree[idb].width);
  262.         }
  263.     }
  264.     }
  265. #endif
  266.  
  267. /********************* main loop ********************************/
  268.   while (!flag.timeout)
  269.     {
  270.       /* go down a level at a time */
  271.       Sdepth++;
  272.       DepthBeyond = Sdepth + ((Sdepth == 1) ? (DEPTHBEYOND >> 1) : DEPTHBEYOND);
  273.  
  274. #if !defined CHESSTOOL
  275. #ifdef QUIETBACKGROUND
  276.       if (!background)
  277. #endif /* QUIETBACKGROUND */
  278.     ShowDepth (' ');
  279. #endif
  280.       /* search at this level returns score of PV */
  281.       score = search (side, 1, Sdepth, alpha, beta, PrVar, &rpt);
  282.       /* save PV as killer */
  283.       for (i = 1; i <= Sdepth; i++)
  284.     killr0[i] = PrVar[i];
  285.  
  286.       /* low search failure re-search with (-inf,score) limits  */
  287.       if (score < alpha)
  288.     {
  289.       reminus++;
  290. #ifdef QUIETBACKGROUND
  291.       if (!background)
  292. #endif /* QUIETBACKGROUND */
  293.         ShowDepth ('-');
  294.       if (TCflag && TCcount < MAXTCCOUNT)
  295.         {
  296.           TCcount = MAXTCCOUNT-1;
  297.           ExtraTime += (6*TCleft);
  298.         }
  299.       score = search (side, 1, Sdepth, -9999, score, PrVar, &rpt);
  300.     }
  301.  
  302.       /* high search failure re-search with (score, +inf) limits */
  303.       if (score > beta && !(root->flags & exact))
  304.     {
  305.       replus++;
  306. #ifdef QUIETBACKGROUND
  307.       if (!background)
  308. #endif /* QUIETBACKGROUND */
  309.         ShowDepth ('+');
  310.       score = search (side, 1, Sdepth, score, 9999, PrVar, &rpt);
  311.     }
  312. /**************** out of search ********************************************/
  313.       if (Sdepth == MaxSearchDepth)
  314.     flag.timeout = true;
  315.  
  316.       else if (TCflag && (Sdepth > (MINDEPTH - 1)) && (TCcount < MAXTCCOUNT))
  317.     {
  318.       if (tmp[1] != PrVar[1] || tmp[2] != PrVar[2])
  319.         {
  320.           TCcount++;
  321.           ExtraTime += TCleft;
  322.         }
  323.  
  324.       if ((abs (score - globalscore) / Sdepth) > ZDELTA)
  325.         {
  326.           TCcount++;
  327.           ExtraTime += TCleft;
  328.         }
  329.     }
  330.       if(TCflag) if ((4 * et) > (2 * ResponseTime + ExtraTime)) flag.timeout = true;
  331. /************************ time control ***********************************/
  332.  
  333.       /* save PV as killer */
  334.       for (i = 1; i <= Sdepth + 1; i++)
  335.     killr0[i] = PrVar[i];
  336.       if (((rootnode.f << 8) | rootnode.t) != PrVar[1])
  337.     {
  338.       for (i = TrPnt[1]; i < TrPnt[2]; i++)
  339.         if (((Tree[i].f << 8) | Tree[i].t) == PrVar[1])
  340.           {
  341.         rootnode = Tree[i];
  342.         break;
  343.           }
  344.     }
  345.       for (i = 1; i <= Sdepth + 1; i++)
  346.     tmp[i] = PrVar[i];
  347.       if(!flag.timeout)Tscore[0] = score;
  348.       /*if (!flag.timeout)*/
  349.       for (i = TrPnt[1]; i < TrPnt[2]; i++)
  350.     pick (i, TrPnt[2] - 1);
  351.       /* if done or nothing good to look at quit */
  352.       if ((rootnode.flags & exact) || (score < -9000))
  353.     flag.timeout = true;
  354. #ifdef DEBUG13
  355.       if (flag.timeout && !background)
  356.     {
  357.       FILE *D;
  358.       int r, c, l;
  359.       struct leaf *xnode;
  360.       D = fopen ("/tmp/DEBUG", "a+");
  361.       fprintf (D, " %d ply %d sco %d TC %d rs %d gl %d cnt %d\n",
  362.            Sdepth, plyscore, score, TCcount, restype,
  363.            globalpnt, TrPnt[2] - TrPnt[1]);
  364.       for (i = 1; tmp[i]; i++)
  365.         {
  366.           algbr (tmp[i] >> 8, tmp[i] & 0xff, 0);
  367.           fprintf (D, "%s ", mvstr[0]);
  368.         }
  369.       fprintf (D, "\n");
  370.       for (i = 1; PrVar[i]; i++)
  371.         {
  372.           algbr (PrVar[i] >> 8, PrVar[i] & 0xff, 0);
  373.           fprintf (D, "%s ", mvstr[0]);
  374.         }
  375.       fprintf (D, "\n");
  376.       algbr (rootnode.f, rootnode.t, rootnode.flags);
  377.       fprintf (D, "%s ", mvstr[0]);
  378.       fprintf (D, "\n");
  379.       fclose (D);
  380.     }
  381. #endif
  382.       /* find the next best move put below root */
  383.       if (!flag.timeout)
  384.     {
  385.       /* */
  386. #if !defined NODYNALPHA
  387.       Jscore = (plyscore + score) >> 1;
  388. #endif
  389.       plyscore = score;
  390.       /* recompute search window */
  391.       beta = score + ((computer == black) ? BBwindow : WBwindow);
  392. #if !defined NODYNALPHA
  393.       alpha = ((Jscore < score) ? Jscore : score) - ((computer == black) ? BAwindow : WAwindow) - abs (Jscore / 12) - 20;
  394. #else
  395.       alpha = score - ((computer == black) ? BAwindow : WAwindow);
  396. #endif
  397.     }
  398.       else
  399.     for (i = 1; i <= Sdepth + 1; i++)
  400.       PrVar[i] = tmp[i];
  401. #if !defined CHESSTOOL
  402. #ifdef QUIETBACKGROUND
  403.       if (!background)
  404. #endif /* QUIETBACKGROUND */
  405.     ShowResults (score, PrVar, '.');
  406. #endif
  407. #ifdef DEBUG4
  408.       if (debuglevel & 16)
  409.     {
  410.       int j;
  411.       printf ("Sdepth %d alpha %d beta %d stage %d\n", Sdepth, alpha, beta, stage);
  412.       for (j = 1; j < 2; j++)
  413.         {
  414.           int idb;
  415.           for (idb = TrPnt[j]; idb < TrPnt[j + 1]; idb++)
  416.         {
  417.           algbr (Tree[idb].f, Tree[idb].t, Tree[idb].flags);
  418.           printf ("level 16 %d-->%d %s %d %d %x\n", Sdepth, idb, mvstr[0], Tree[idb].score, Tree[idb].width, Tree[idb].flags);
  419.         }
  420.         }
  421.     }
  422. #endif
  423.  
  424.     }
  425. /******************************* end of main loop ***********************************/
  426.   /* background mode */
  427.   if (iop == 2)
  428.     return;
  429. #ifdef DEBUG4
  430.   if (debuglevel & 4)
  431.     {
  432.       int j;
  433.       printf ("Sdepth %d alpha %d beta %d stage %d\n", Sdepth, alpha, beta, stage);
  434.       for (j = 1; j < 2; j++)
  435.     {
  436.       int idb;
  437.       for (idb = TrPnt[j]; idb < TrPnt[j + 1]; idb++)
  438.         {
  439.           algbr (Tree[idb].f, Tree[idb].t, Tree[idb].flags);
  440.           printf ("level 4 %d-->%d %s %d %d\n", j, idb, mvstr[0], Tree[idb].score, Tree[idb].width);
  441.         }
  442.     }
  443.     }
  444. #endif
  445.  
  446.   if (rpt >= 2)
  447.     {
  448.       rootnode.flags |= draw;
  449.       DRAW = CP[101];        /*Repetition*/
  450.     }
  451.   else
  452.     /* if no moves and not in check then draw */
  453.   if ((rootnode.score == -9999) && !(SqAtakd (PieceList[side][0], xside)))
  454.     {
  455.       rootnode.flags |= draw;
  456.       DRAW = CP[87];        /*No moves*/
  457.     }
  458.   else if (GameCnt == MAXMOVES)
  459.     {
  460.       rootnode.flags |= draw;
  461.       DRAW = CP[80];        /*Max Moves*/
  462.     }
  463.  
  464.   /* not in book so set hint to guessed move for other side */
  465.   if (!bookflag)
  466.     hint = ((tmp[1]) ? tmp[2] : 0);
  467.  
  468.   /* if not mate or draw make move and output it */
  469.   if (((score > -9999) && (rpt <= 2)) || (rootnode.flags & draw))
  470.     {
  471.       MakeMove (side, &rootnode, &tempb, &tempc, &tempsf, &tempst, &INCscore);
  472. #if !defined NOMATERIAL
  473.       if (flag.material && !pmtl[black] && !pmtl[white] && (mtl[white] < (valueR + valueK)) && (mtl[black] < (valueR + valueK)))
  474.     {
  475.       rootnode.flags |= draw;
  476.       DRAW = CP[224];    /*No pieces*/
  477.     }
  478.       else
  479. #endif
  480.       if (!PieceCnt[black] && !PieceCnt[white])
  481.     {
  482.       rootnode.flags |= draw;
  483.       DRAW = CP[88];    /*No pieces*/
  484.     }
  485.       algbr (rootnode.f, rootnode.t, (short) rootnode.flags);
  486.     }
  487.   else {
  488.     algbr (0, 0, 0);        /* Zero move string when mate. */
  489.     rootnode.score = score;    /* When mate, ignore distinctions! --SMC */
  490.   }
  491.   g = &GameList[GameCnt];
  492.   if(g->flags & capture && g->piece == king)
  493.     {flag.mate = flag.illegal = true;}
  494.   /* If Time Control get the elapsed time */
  495.   if (TCflag)
  496.     ElapsedTime (1);
  497.   OutputMove ();
  498.   /* if mate set flag */
  499.   if ((score == -9999 || score == 9998) )
  500.     flag.mate = true;
  501.   /* if mate clear hint */
  502.   if (flag.mate)
  503.     hint = 0;
  504.   /* if pawn move or capture or castle or promote zero repitition array */
  505.   if ((board[rootnode.t] == pawn) || (rootnode.flags & (capture | cstlmask | promote)))
  506.     {
  507.       Game50 = GameCnt;
  508.       ZeroRPT ();
  509.     }
  510.   /* add move to game list */
  511.   g->score = score;
  512.   g->nodes = NodeCnt;
  513.   g->time = (short) et;
  514.   g->depth = Sdepth;
  515. #ifdef DEBUG40
  516.   g->d1 = TCcount;
  517.   g->d2 = ResponseTime ;
  518.   g->d3 = ExtraTime;
  519.   g->d4 = TCleft;
  520.   g->d5 = et;
  521.   g->d6 = TimeControl.clock[side];
  522.   g->d7 = d7flag;
  523. #endif
  524.   /* update time comtrol info */
  525.   if (TCflag)
  526.     {
  527. #if defined CHESSTOOL || defined XBOARD
  528.       TimeControl.clock[side] -= (et + OperatorTime + 45);
  529. #else
  530.       TimeControl.clock[side] -= (et + OperatorTime);
  531. #endif
  532.       /* finished our required moves - setup the next set */
  533.       if (--TimeControl.moves[side] == 0)
  534.     {
  535.       if (XC)
  536.         if (XCmore < XC)
  537.           {
  538.         TCmoves = XCmoves[XCmore];
  539.         TCminutes = XCminutes[XCmore];
  540.         TCseconds = XCseconds[XCmore];
  541.         XCmore++;
  542.           }
  543.       SetTimeControl ();
  544.     }
  545.     }
  546.   /* check for end conditions */
  547.   if ((rootnode.flags & draw) /*&& flag.bothsides*/ )
  548.      flag.mate = true;
  549.   else if (GameCnt == MAXMOVES)
  550.     {
  551.       flag.mate = true;
  552.     }
  553.   /* out of move store, you loose */
  554.   else
  555.     /* switch to other side */
  556.     player = xside;
  557.   Sdepth = 0;
  558. }
  559.  
  560. int
  561. search (short int side,
  562.     register short int ply,
  563.     register short int depth,
  564.     short int alpha,
  565.     short int beta,
  566.     short unsigned int *bstline,
  567.     short int *rpt)
  568.  
  569. /*
  570.  * Perform an alpha-beta search to determine the score for the current board
  571.  * position. If depth <= 0 only capturing moves, pawn promotions and
  572.  * responses to check are generated and searched, otherwise all moves are
  573.  * processed. The search depth is modified for check evasions, certain
  574.  * re-captures and threats. Extensions may continue for up to 11 ply beyond
  575.  * the nominal search depth.
  576.  */
  577.  
  578.  
  579. {
  580.   register short j, pnt;
  581.   short tempb, tempc, tempsf, tempst, cf;
  582.   short xside, pbst, score, rcnt, slk, InChk;
  583.   unsigned short mv, nxtline[MAXDEPTH];
  584.   struct leaf *node, tmp;
  585.   short best;
  586.   short bestwidth = 0;
  587.  
  588.   NodeCnt++;
  589.   /* look every ZNODE nodes for a timeout */
  590.   if (TCflag || MaxResponseTime)
  591.     {
  592.       if (NodeCnt > ETnodes)
  593.     {
  594.       ElapsedTime (2);
  595.       if (Sdepth > MINDEPTH && flag.musttimeout)
  596.         {
  597.           flag.timeout = true;
  598.           flag.musttimeout = false;
  599.         }
  600.       else if ((et >= (ResponseTime + ExtraTime)) && Sdepth > MINDEPTH)
  601.                {/* try to extend to finish ply */
  602.                 if (TCflag && TCcount < MAXTCCOUNT)
  603.                          { TCcount += 1; ExtraTime += TCleft; 
  604. #ifdef DEBUG40
  605.         d7flag++;
  606. #endif
  607.                }
  608.                 else flag.timeout = true;
  609.                }
  610.     }
  611.  
  612.     }
  613.   else if (flag.musttimeout && Sdepth > MINDEPTH)
  614.     {
  615.       flag.timeout = true;
  616.       flag.musttimeout = false;
  617.     }
  618.  
  619.   xside = side ^ 1;
  620.   /* slk is lone king indicator for either side */
  621.   score = evaluate (side, ply, alpha, beta, INCscore, &slk, &InChk);
  622.  
  623.   /*
  624.    * check for possible repitition if so call repitition - rpt is repeat
  625.    * count
  626.    */
  627.   if ((ply <= Sdepth + 3) && rpthash[side][hashkey & 0xFF] > 0)
  628.     {
  629.       repetition (rpt);
  630.  
  631.       /*
  632.        * repeat position >2 don't need to return score it's taken care of
  633.        * above
  634.        */
  635.       if (*rpt == 1 )  score /= 2;
  636.     }
  637.   else
  638.     *rpt = 0;
  639.  
  640.   /* score > 9000 its a draw or mate */
  641.   if (score > 9000)
  642.     {
  643.       bstline[ply] = 0;
  644.       return (score);
  645.     }
  646.   /* Do we need to add depth because of special conditions */
  647.   /* if in check or pawn threat or in capture sequence search deeper */
  648. /*************************************** depth extensions ***********************************/
  649.   if (depth > 0)
  650.     {
  651.       /* Allow opponent a chance to check again */
  652.       if (InChk)
  653.     depth = (depth < 2) ? 2 : depth;
  654.       else if (PawnThreat[ply - 1] ||
  655.            (flag.rcptr && (score > alpha) &&
  656.       (score < beta) && (ply > 2) && CptrFlag[ply - 1] && CptrFlag[ply - 2]))
  657.     ++depth;
  658.     }
  659.   else
  660.     {
  661.       if (score >= alpha &&
  662.       (InChk || PawnThreat[ply - 1] || (hung[side] > 1 && ply == Sdepth + 1)))
  663.     depth = 1;
  664.       else if (score <= beta &&
  665.            ((ply < Sdepth + 4) && (ply > 4) &&
  666.         ChkFlag[ply - 2] && ChkFlag[ply - 4] &&
  667.         ChkFlag[ply - 2] != ChkFlag[ply - 4]))
  668.     depth = 1;
  669.     }
  670. /*******************************************************************************************/
  671.   /* try the local transition table if it's there */
  672. #if ttblsz
  673.   if (flag.hash && ply > 1)
  674.     {
  675.       if (ProbeTTable (side, depth, ply, &alpha, &beta, &score) == true)
  676.     {
  677.       bstline[ply] = PV;
  678.       bstline[ply + 1] = 0;
  679. #ifdef DEBUG4
  680.       if (debuglevel & 64)
  681.         {
  682.           algbr (PV >> 8, PV & 0xff, 0);
  683.           printf ("-get-> d=%d s=%d p=%d a=%d b=%d %s\n", depth, score, ply, alpha, beta, mvstr[0]);
  684.         }
  685. #endif
  686.       if (beta == -20000)
  687.         return (score);
  688.       if (alpha > beta)
  689.         return (alpha);
  690.     }
  691. #ifdef HASHFILE
  692.       /* ok try the transition file if its there */
  693.       else if (hashfile && (depth > HashDepth) && (GameCnt < HashMoveLimit)
  694.      && (ProbeFTable (side, depth, ply, &alpha, &beta, &score) == true))
  695.     {
  696.       int hgood = false;
  697.       int f = PV >> 8;
  698.       int t = PV & 0x3f;
  699.       register int i;
  700.       /*
  701.            * if you find something put it in the local table for future
  702.            * reference
  703.            */
  704.       hgood = false;
  705.       for (i = TrPnt[ply]; i < TrPnt[ply + 1]; i++)
  706.         {
  707.           if (Tree[i].f == f && Tree[i].t == t)
  708.         {
  709.           hgood = true;
  710.           break;
  711.         }
  712.         }
  713.       if (hgood)
  714.         {
  715.           PutInTTable (side, score, depth, ply, alpha, beta, PV);
  716.           bstline[ply] = PV;
  717.           bstline[ply + 1] = 0;
  718.           if (beta == -20000)
  719.         return (score);
  720.           if (alpha > beta)
  721.         return (alpha);
  722.         }
  723. #ifdef DEBUG10
  724.       else
  725.         {
  726.           FILE *D;
  727.           int r, c, l;
  728.           struct leaf *xnode;
  729.           D = fopen ("/tmp/DEBUG", "w");
  730.           pnt = TrPnt[2];
  731.           fprintf (D, "hashfile failure\n");
  732.           algbr (PV >> 8, PV & 0x3f, 0);
  733.           fprintf (D, "inout move is %s\n", mvstr);
  734.           fprintf (D, "legal move are \n");
  735.           for (r = TrPnt[ply]; r < TrPnt[ply + 1]; r++)
  736.         {
  737.           xnode = &Tree[r];
  738.           algbr (xnode->f, xnode->t, (short) xnode->flags);
  739.           fprintf (D, "%s %s %s %s\n", mvstr[0], mvstr[1], mvstr[2], mvstr[3]);
  740.         }
  741.           fprintf (D, "\n current board is\n");
  742.           for (r = 7; r >= 0; r--)
  743.         {
  744.           for (c = 0; c <= 7; c++)
  745.             {
  746.               l = locn (r, c);
  747.               if (color[l] == neutral)
  748.             fprintf (D, " -");
  749.               else if (color[l] == white)
  750.             fprintf (D, " %c", qxx[board[l]]);
  751.               else
  752.             fprintf (D, " %c", pxx[board[l]]);
  753.             }
  754.           fprintf (D, "\n");
  755.         }
  756.           fprintf (D, "\n");
  757.           fclose (D);
  758.         }
  759. #endif
  760.     }
  761. #endif /* HASHFILE */
  762.     }
  763.  
  764. #endif /* ttblsz */
  765.  
  766.   /*
  767.    * if more then DepthBeyond ply past goal depth or at goal depth and
  768.    * score > beta quit - means we are out of the window
  769.    */
  770.   if (ply > DepthBeyond || (depth < 1 && score > beta))
  771.     {
  772.       return (score);
  773.     }
  774.  
  775.   /*
  776.    * if below first ply and not at goal depth generate all moves else only
  777.    * capture moves
  778.    */
  779.   if (ply > 1)
  780.     if (depth > 0)
  781.       {
  782.     MoveList (side, ply);
  783.       }
  784.     else
  785.       CaptureList (side, ply);
  786.  
  787.   /* no moves return what we have */
  788.  
  789.   /*
  790.    * normally a search will continue til past goal and no more capture
  791.    * moves exist
  792.    */
  793.   /* unless it hits DepthBeyond */
  794.   if (TrPnt[ply] == TrPnt[ply + 1])
  795.     {
  796.       return (score);
  797.     }
  798.   cf = (depth < 1 && ply > Sdepth + 1 && !ChkFlag[ply - 2] && !slk);
  799.  
  800.   /* if not at goal set best = -inf else current score */
  801.   best = ((depth > 0) ? -12000 : score);
  802.   /* if best so far is better than alpha set alpha to best */
  803.   if (best > alpha)
  804.     alpha = best;
  805.   /********************** main loop ************************************************************************/
  806.   /* look at each move until no more or beta cutoff */
  807.   for (pnt = pbst = TrPnt[ply]; pnt < TrPnt[ply + 1] && best <= beta; pnt++)
  808.     {
  809.       /* find the most interesting looking of the remaining moves */
  810.       pick (pnt, TrPnt[ply + 1] - 1);
  811.  
  812.       node = &Tree[pnt];
  813.       /* is this a forbidden move */
  814.       if (ply == 1 && node->score == -32768)
  815.     continue;
  816.       nxtline[ply + 1] = 0;
  817.       if (cf && score + node->score < alpha)
  818.     break;
  819. #if !defined CHESSTOOL
  820.       /* if at top level */
  821.       if (ply == 1)
  822.     {            /* at the top update search status */
  823.       if (flag.post)
  824. #ifdef QUIETBACKGROUND
  825.         if (!background)
  826. #endif /* QUIETBACKGROUND */
  827.           ShowCurrentMove (pnt, node->f, node->t);
  828.     }
  829. #endif
  830.       if (!(node->flags & exact))
  831.     {
  832.       /* make the move and go deeper */
  833.       MakeMove (side, node, &tempb, &tempc, &tempsf, &tempst, &INCscore);
  834.       CptrFlag[ply] = (node->flags & capture);
  835.       PawnThreat[ply] = (node->flags & pwnthrt);
  836.       Tscore[ply] = node->score;
  837.       PV = node->reply;
  838.       node->score = -search (xside, ply + 1,
  839.                  ((depth > 0) ? depth - 1 : 0),
  840.                  -beta, -alpha,
  841.                  nxtline, &rcnt);
  842.       node->width = (ply % 2 == 1) ? (TrPnt[ply + 2] - TrPnt[ply + 1]) : 0;
  843.       if (abs (node->score) > 9000)
  844.         node->flags |= exact;
  845.       else if (rcnt == 1) node->score /= 2;
  846.       if ((rcnt >= 2 || GameCnt - Game50 > 99 || (node->score == 9999 - ply && !ChkFlag[ply])))
  847.         {
  848.           node->flags |= (draw | exact);
  849.           DRAW = CP[58];    /* Draw */
  850.           node->score = ((side == computer) ? contempt : -contempt);
  851.         }
  852.       node->reply = nxtline[ply + 1];
  853.       /* reset to try next move */
  854.       UnmakeMove (side, node, &tempb, &tempc, &tempsf, &tempst);
  855.     }
  856.       /* if best move so far */
  857.  
  858.       if (!flag.timeout && ((node->score > best) || ((node->score == best) && (node->width > bestwidth))))
  859.     {
  860.       /* all things being equal pick the denser part of the tree */
  861.       bestwidth = node->width;
  862.  
  863.       /*
  864.            * if not at goal depth and better than alpha and not an exact
  865.            * score increment by depth
  866.            */
  867.       if (depth > 0 && node->score > alpha && !(node->flags & exact))
  868.         node->score += depth;
  869.       best = node->score;
  870.       pbst = pnt;
  871.       if (best > alpha)
  872.         {
  873.           alpha = best;
  874.         }
  875.       /* update best line */
  876.       for (j = ply + 1; nxtline[j] > 0; j++)
  877.         bstline[j] = nxtline[j];
  878.       bstline[j] = 0;
  879.       bstline[ply] = (node->f << 8) | node->t;
  880.       /* if at the top */
  881.       if (ply == 1)
  882.         {
  883.  
  884.           /*
  885.                * if its better than the root score make it the root
  886.                */
  887.           if ((best > root->score) || ((best == root->score) && (bestwidth > root->width)))
  888.         {
  889.           tmp = Tree[pnt];
  890.           for (j = pnt - 1; j >= 0; j--)
  891.             Tree[j + 1] = Tree[j];
  892.           Tree[0] = tmp;
  893.           pbst = 0;
  894.         }
  895. #if !defined CHESSTOOL
  896. #ifdef QUIETBACKGROUND
  897.           if (!background)
  898. #endif /* QUIETBACKGROUND */
  899.         if (Sdepth > 2)
  900.           if (best > beta)
  901.             {
  902.               ShowResults (best, bstline, '+');
  903.             }
  904.           else if (best < alpha)
  905.             {
  906.               ShowResults (best, bstline, '-');
  907.             }
  908.           else
  909.             ShowResults (best, bstline, '&');
  910. #endif
  911.           restype = (best < alpha) ? false : true;
  912.         }
  913.     }
  914.       if (Sdepth > MINDEPTH && flag.timeout)
  915.     {
  916.       if (ply == 1)
  917.         globalpnt = (pnt);
  918.       return (Tscore[ply - 1]);
  919.     }
  920.     }
  921.  
  922.   /******************************************************************************************/
  923.   globalpnt = (pnt);
  924.   node = &Tree[pbst];
  925.   mv = (node->f << 8) | node->t;
  926.  
  927.   /*
  928.    * we have a move so put it in local table - if it's already there done
  929.    * else if not there or needs to be updated also put it in hashfile
  930.    */
  931. #if ttblsz
  932.   if (flag.hash && ply <= Sdepth && *rpt == 0 && best == alpha)
  933.     {
  934.       if (PutInTTable (side, best, depth, ply, alpha, beta, mv)
  935. #ifdef HASHFILE
  936.       && hashfile && (depth > HashDepth) && (GameCnt < HashMoveLimit))
  937.     {
  938.       PutInFTable (side, best, depth, ply, alpha, beta, node->f, node->t);
  939.     }
  940. #else
  941.     );
  942. #endif /* HASHFILE */
  943.     }
  944.  
  945. #endif /* ttblsz */
  946.   if (depth > 0)
  947.     {
  948. #ifdef HISTORY
  949.       j = (node->f << 6) | node->t;
  950.       if (side == black)
  951.     j |= 0x4000;
  952.       if (history[j] < HISTORYLIM)
  953.     history[j] += (unsigned char) depth << 1;
  954. #endif
  955.       if (node->t != (GameList[GameCnt].gmove & 0xFF))
  956.     if (best <= beta)
  957.       killr3[ply] = mv;
  958.     else if (mv != killr1[ply])
  959.       {
  960.         killr2[ply] = killr1[ply];
  961.         killr1[ply] = mv;
  962.       }
  963.       killr0[ply] = ((best > 9000) ? mv : 0);
  964.     }
  965.  
  966.   return (best);
  967. }
  968.  
  969.  
  970.  
  971.  
  972. int
  973. castle (short int side, short int kf, short int kt, short int iop)
  974.  
  975. /* Make or Unmake a castling move. */
  976.  
  977. {
  978.   register short rf, rt, t0, xside;
  979.  
  980.   xside = side ^ 1;
  981.   if (kt > kf)
  982.     {
  983.       rf = kf + 3;
  984.       rt = kt - 1;
  985.     }
  986.   else
  987.     {
  988.       rf = kf - 4;
  989.       rt = kt + 1;
  990.     }
  991.   if (iop == 0)
  992.     {
  993.       if (kf != kingP[side] ||
  994.       board[kf] != king ||
  995.       board[rf] != rook ||
  996.       color[kf] != side ||
  997.       color[rf] != side ||
  998.       Mvboard[kf] != 0 ||
  999.       Mvboard[rf] != 0 ||
  1000.       color[kt] != neutral ||
  1001.       color[rt] != neutral ||
  1002.       color[kt - 1] != neutral ||
  1003.       SqAtakd (kf, xside) ||
  1004.       SqAtakd (kt, xside) ||
  1005.       SqAtakd (rt, xside))
  1006.     return (false);
  1007.     }
  1008.   else
  1009.     {
  1010.       if (iop == 1)
  1011.     {
  1012.       castld[side] = true;
  1013.       Mvboard[kf]++;
  1014.       Mvboard[rf]++;
  1015.     }
  1016.       else
  1017.     {
  1018.       castld[side] = false;
  1019.       Mvboard[kf]--;
  1020.       Mvboard[rf]--;
  1021.       t0 = kt;
  1022.       kt = kf;
  1023.       kf = t0;
  1024.       t0 = rt;
  1025.       rt = rf;
  1026.       rf = t0;
  1027.     }
  1028.       board[kt] = king;
  1029.       color[rt] = color[kt] = side;
  1030.       Pindex[kt] = 0;
  1031.       board[kf] = no_piece;
  1032.       color[rf] = color[kf] = neutral;
  1033.       board[rt] = rook;
  1034.       Pindex[rt] = Pindex[rf];
  1035.       board[rf] = no_piece;
  1036.       PieceList[side][Pindex[kt]] = kt;
  1037.       PieceList[side][Pindex[rt]] = rt;
  1038.       UpdateHashbd (side, king, kf, kt);
  1039.       UpdateHashbd (side, rook, rf, rt);
  1040.     }
  1041.   return (true);
  1042. }
  1043.  
  1044.  
  1045. void
  1046. EnPassant (short int xside, short int f, short int t, short int iop)
  1047.  
  1048. /*
  1049.  * Make or unmake an en passant move.
  1050.  */
  1051.  
  1052. {
  1053.   register short l;
  1054.  
  1055.   l = t + ((t > f) ? -8 : 8);
  1056.   if (iop == 1)
  1057.     {
  1058.       board[l] = no_piece;
  1059.       color[l] = neutral;
  1060.     }
  1061.   else
  1062.     {
  1063.       board[l] = pawn;
  1064.       color[l] = xside;
  1065.     }
  1066.   InitializeStats ();
  1067.   if (iop != 1)
  1068.     epsquare = t;
  1069. }
  1070.  
  1071.  
  1072. void
  1073. UpdatePieceList (short int side, short int sq, short int iop)
  1074.  
  1075. /*
  1076.  * Update the PieceList and Pindex arrays when a piece is captured or when a
  1077.  * capture is unmade.
  1078.  */
  1079.  
  1080. {
  1081.   register short i;
  1082.  
  1083.   if (iop == 1)
  1084.     {
  1085.       PieceCnt[side]--;
  1086.       for (i = Pindex[sq]; i <= PieceCnt[side]; i++)
  1087.     {
  1088.       PieceList[side][i] = PieceList[side][i + 1];
  1089.       Pindex[PieceList[side][i]] = i;
  1090.     }
  1091.     }
  1092.   else
  1093.     {
  1094.       PieceCnt[side]++;
  1095.       PieceList[side][PieceCnt[side]] = sq;
  1096.       Pindex[sq] = PieceCnt[side];
  1097.     }
  1098. }
  1099.  
  1100. void
  1101. MakeMove (short int side,
  1102.       struct leaf * node,
  1103.       short int *tempb,    /* color of to square */
  1104.       short int *tempc,    /* piece at to square */
  1105.       short int *tempsf,    /* static value of piece on from */
  1106.       short int *tempst,    /* static value of piece on to */
  1107.       short int *INCscore)    /* score increment for pawn structure change */
  1108.  
  1109. /*
  1110.  * Update Arrays board[], color[], and Pindex[] to reflect the new board
  1111.  * position obtained after making the move pointed to by node. Also update
  1112.  * miscellaneous stuff that changes when a move is made.
  1113.  */
  1114.  
  1115. {
  1116.   register short f, t, xside, ct, cf;
  1117.   register struct GameRec *g;
  1118.  
  1119.   xside = side ^ 1;
  1120.   g = &GameList[++GameCnt];
  1121.   g->hashkey = hashkey;
  1122.   g->hashbd = hashbd;
  1123.   f = node->f;
  1124.   t = node->t;
  1125.   epsquare = -1;
  1126.   FROMsquare = f;
  1127.   TOsquare = t;
  1128.   *INCscore = 0;
  1129.   g->Game50 = Game50;
  1130.   g->gmove = (f << 8) | t;
  1131.   g->flags = node->flags;
  1132.   if (node->flags & cstlmask)
  1133.     {
  1134.       g->piece = no_piece;
  1135.       g->color = side;
  1136.       (void) castle (side, f, t, 1);
  1137.       Game50 = GameCnt;
  1138.     }
  1139.   else
  1140.     {
  1141.       if (!(node->flags & capture) && (board[f] != pawn))
  1142.     rpthash[side][hashkey & 0xFF]++;
  1143.       else
  1144.     Game50 = GameCnt;
  1145.       *tempsf = svalue[f];
  1146.       *tempst = svalue[t];
  1147.       g->piece = *tempb = board[t];
  1148.       g->color = *tempc = color[t];
  1149.       if (*tempc != neutral)
  1150.     {
  1151.       UpdatePieceList (*tempc, t, 1);
  1152.       /* if capture decrement pawn count */
  1153.       if (*tempb == pawn)
  1154.         {
  1155.           --PawnCnt[*tempc][column (t)];
  1156.         }
  1157.       if (board[f] == pawn)
  1158.         {
  1159.           cf = column (f);
  1160.           ct = column (t);
  1161.           /* move count from from to to */
  1162.           --PawnCnt[side][cf];
  1163.           ++PawnCnt[side][ct];
  1164.  
  1165.           /*
  1166.                * calculate increment for pawn structure changes
  1167.                */
  1168.           /* doubled or more - */
  1169.           if (PawnCnt[side][ct] > (1 + PawnCnt[side][cf]))
  1170.         *INCscore -= 15;
  1171.           /* went to empty column + */
  1172.           else if (PawnCnt[side][ct] < 1 + PawnCnt[side][cf])
  1173.         *INCscore += 15;
  1174.  
  1175.           /*
  1176.                * went to outside col or empty col on one side ????????
  1177.                */
  1178.           else if (ct == 0 || ct == 7 || PawnCnt[side][ct + ct - cf] == 0)
  1179.         *INCscore -= 15;
  1180.         }
  1181.       mtl[xside] -= value[*tempb];
  1182.       if (*tempb == pawn)
  1183.         pmtl[xside] -= valueP;
  1184.       UpdateHashbd (xside, *tempb, -1, t);
  1185.       *INCscore += *tempst;
  1186.       Mvboard[t]++;
  1187.     }
  1188.       color[t] = color[f];
  1189.       board[t] = board[f];
  1190.       svalue[t] = svalue[f];
  1191.       Pindex[t] = Pindex[f];
  1192.       PieceList[side][Pindex[t]] = t;
  1193.       color[f] = neutral;
  1194.       board[f] = no_piece;
  1195.       if (board[t] == pawn)
  1196.     if (t - f == 16)
  1197.       epsquare = f + 8;
  1198.     else if (f - t == 16)
  1199.       epsquare = f - 8;
  1200.       if (node->flags & promote)
  1201.     {
  1202.       board[t] = node->flags & pmask;
  1203.       if (board[t] == queen)
  1204.         HasQueen[side]++;
  1205.       else if (board[t] == rook)
  1206.         HasRook[side]++;
  1207.       else if (board[t] == bishop)
  1208.         HasBishop[side]++;
  1209.       else if (board[t] == knight)
  1210.         HasKnight[side]++;
  1211.       --PawnCnt[side][column (t)];
  1212.       mtl[side] += value[board[t]] - valueP;
  1213.       pmtl[side] -= valueP;
  1214.       UpdateHashbd (side, pawn, f, -1);
  1215.       UpdateHashbd (side, board[t], f, -1);
  1216.       *INCscore -= *tempsf;
  1217.     }
  1218.       if (node->flags & epmask)
  1219.     EnPassant (xside, f, t, 1);
  1220.       else
  1221.     UpdateHashbd (side, board[t], f, t);
  1222.       Mvboard[f]++;
  1223.     }
  1224. }
  1225.  
  1226. void
  1227. UnmakeMove (short int side,
  1228.         struct leaf * node,
  1229.         short int *tempb,
  1230.         short int *tempc,
  1231.         short int *tempsf,
  1232.         short int *tempst)
  1233.  
  1234. /*
  1235.  * Take back a move.
  1236.  */
  1237.  
  1238. {
  1239.   register short f, t, xside;
  1240.  
  1241.   xside = side ^ 1;
  1242.   f = node->f;
  1243.   t = node->t;
  1244.   epsquare = -1;
  1245.   Game50 = GameList[GameCnt--].Game50;
  1246.   if (node->flags & cstlmask)
  1247.     (void) castle (side, f, t, 2);
  1248.   else
  1249.     {
  1250.       color[f] = color[t];
  1251.       board[f] = board[t];
  1252.       svalue[f] = *tempsf;
  1253.       Pindex[f] = Pindex[t];
  1254.       PieceList[side][Pindex[f]] = f;
  1255.       color[t] = *tempc;
  1256.       board[t] = *tempb;
  1257.       svalue[t] = *tempst;
  1258.       if (node->flags & promote)
  1259.     {
  1260.       board[f] = pawn;
  1261.       ++PawnCnt[side][column (t)];
  1262.       mtl[side] += valueP - value[node->flags & pmask];
  1263.       pmtl[side] += valueP;
  1264.       UpdateHashbd (side, (short) node->flags & pmask, -1, t);
  1265.       UpdateHashbd (side, pawn, -1, t);
  1266.     }
  1267.       if (*tempc != neutral)
  1268.     {
  1269.       UpdatePieceList (*tempc, t, 2);
  1270.       if (*tempb == pawn)
  1271.         {
  1272.           ++PawnCnt[*tempc][column (t)];
  1273.         }
  1274.       if (board[f] == pawn)
  1275.         {
  1276.           --PawnCnt[side][column (t)];
  1277.           ++PawnCnt[side][column (f)];
  1278.         }
  1279.       mtl[xside] += value[*tempb];
  1280.       if (*tempb == pawn)
  1281.         pmtl[xside] += valueP;
  1282.       UpdateHashbd (xside, *tempb, -1, t);
  1283.       Mvboard[t]--;
  1284.     }
  1285.       if (node->flags & epmask)
  1286.     EnPassant (xside, f, t, 2);
  1287.       else
  1288.     UpdateHashbd (side, board[f], f, t);
  1289.       Mvboard[f]--;
  1290.       if (!(node->flags & capture) && (board[f] != pawn))
  1291.     rpthash[side][hashkey & 0xFF]--;
  1292.     }
  1293. }
  1294.  
  1295.  
  1296. void
  1297. InitializeStats (void)
  1298.  
  1299. /*
  1300.  * Scan thru the board seeing what's on each square. If a piece is found,
  1301.  * update the variables PieceCnt, PawnCnt, Pindex and PieceList. Also
  1302.  * determine the material for each side and set the hashkey and hashbd
  1303.  * variables to represent the current board position. Array
  1304.  * PieceList[side][indx] contains the location of all the pieces of either
  1305.  * side. Array Pindex[sq] contains the indx into PieceList for a given
  1306.  * square.
  1307.  */
  1308.  
  1309. {
  1310.   register short i, sq;
  1311.  
  1312.   epsquare = -1;
  1313.   for (i = 0; i < 8; i++)
  1314.     {
  1315.       PawnCnt[white][i] = PawnCnt[black][i] = 0;
  1316.     }
  1317.   mtl[white] = mtl[black] = pmtl[white] = pmtl[black] = 0;
  1318.   PieceCnt[white] = PieceCnt[black] = 0;
  1319.   hashbd = hashkey = 0;
  1320.   for (sq = 0; sq < 64; sq++)
  1321.     if (color[sq] != neutral)
  1322.       {
  1323.     mtl[color[sq]] += value[board[sq]];
  1324.     if (board[sq] == pawn)
  1325.       {
  1326.         pmtl[color[sq]] += valueP;
  1327.         ++PawnCnt[color[sq]][column (sq)];
  1328.       }
  1329.     Pindex[sq] = ((board[sq] == king) ? 0 : ++PieceCnt[color[sq]]);
  1330.  
  1331.     PieceList[color[sq]][Pindex[sq]] = sq;
  1332.     hashbd ^= hashcode[color[sq]][board[sq]][sq].bd;
  1333.     hashkey ^= hashcode[color[sq]][board[sq]][sq].key;
  1334.       }
  1335. }
  1336.